/**
 * 项目名称：捕捉按键输入
 * 单片机：STC8G1K08
 * 频率：12Mhz
 * PCB:1603120A_Y3
 * 学习目标：捕捉按键消除抖动
 */

#include "intrins.h"
#include "stc8g.h" //加载此头文件以后不需要再加载reg51.h

#define LED_0 P35
#define LED_1 P34
#define LED_2 P10
#define LED_3 P11
#define LED_4 P16
#define LED_5 P17
#define LED_6 P54
#define LED_7 P55

#define KEY_1 P32
#define KEY_2 P33

unsigned char ledState; // led状态
unsigned char bits;
volatile unsigned char timer2_t = 20; // 1000 / 50 = 20

void Delay10ms() //@12.000MHz
{
    unsigned char i, j;

    _nop_();
    _nop_();
    i = 156;
    j = 213;
    do {
        while (--j)
            ;
    } while (--i);
}

//刷新LED状态
void led_update_display() {
    LED_0 = ledState & (0x01 << 0);
    LED_1 = ledState & (0x01 << 1);
    LED_2 = ledState & (0x01 << 2);
    LED_3 = ledState & (0x01 << 3);
    LED_4 = ledState & (0x01 << 4);
    LED_5 = ledState & (0x01 << 5);
    LED_6 = ledState & (0x01 << 6);
    LED_7 = ledState & (0x01 << 7);
}

//初始化IO
void pin_init() {
    P1M1 = 0x00;
    P1M0 = (0x01 << 7) | (0x01 << 6) | (0x01 << 1) | (0x01 << 0);

    // P3M1 = (0x01 << 3) | (0x01 << 2);
    P3M1 = 0x00;
    P3M0 = (0x01 << 5) | (0x01 << 4);

    // P33 = 1; //开内部上拉
    // P32 = 1;

    P5M1 = 0x00;
    P5M0 = (0x01 << 5) | (0x01 << 4);
}

//定时器2 初始化 10ms@12Mhz
void timer2_init() {
    AUXR &= 0xFB; //定时器时钟12T模式 1111 1011
    T2L = 0xF0;   //设置定时初值
    T2H = 0xD8;   //设置定时初值
    AUXR |= 0x10; //定时器2开始计时
}

//位移LED，每调用1次左移1个位
void shift_led() {
    bits++;
    if (bits >= 8) {
        bits = 0;
    }
    ledState = 0x01 << bits;
}

// avoid vibrat
void scan_key_1_vibrate() {
    static unsigned char last = 0xFF;
    //下降沿
    if (!KEY_1 && last) {
        shift_led();          //移位
        led_update_display(); //刷新显示
    }
    last = KEY_1;
}

//延时消抖
void scan_key_2_avoid_vibrate() {
    static unsigned char last = 0xFF;
    //下降沿
    if (!KEY_2 && last) {
        Delay10ms();          //延时等待抖动过去
        shift_led();          //移位
        led_update_display(); //刷新显示
    }
    last = KEY_2;
}

void main() {

    pin_init();
    timer2_init();

    ledState = 0x01;
    bits = 0;
    led_update_display(); //刷新显示

    IE2 |= 0x04; // ET2 置1 使能(允许)定时器2中断
    EA = 1;      //使能总中断 (打开中断总开关)

    while (1) {
        //scan_key_1_vibrate();  //放在这里是轮询
        scan_key_2_avoid_vibrate();
    }
}

//定时器2 中断函数
void time2_ISR() interrupt 12 {
    scan_key_1_vibrate(); //放在这里是就是用定时器扫描
}